home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS04.ADF
/
text
/
inputdevice.txt
< prev
next >
Wrap
Text File
|
1985-12-04
|
18KB
|
456 lines
/* input device text */
PRELIMINARY INFORMATION... CURRENTLY UNDER REVIEW.
DOESN'T DESCRIBE THE set mouse port FUNCTIONS.
MAY CONTAIN MINOR INACCURACIES IN THE SAMPLE PROGRAM SEGMENT.
(printed version available approx 11/18/85, reviewed and correct-
ed).
Rob Peck.
Chapter 1
Input Device
This chapter describes the Amiga input device, which is a combi-
nation of three other devices: keyboard device, gameport device,
and timer device. The input device merges separate input event
streams from the keyboard, mouse, and timer into a single stream.
This single stream can then be interpreted by the prioritized
linked list of input handlers that are watching the input stream.
1.1. OVERVIEW
The input device is automatically opened by AmigaDOS by any call
to open the console device. When the input device is opened, a
task, appropriately named ``input.device'', is started. The
input device task communicates directly with the keyboard device
to obtain raw key inputs. It also communicates with the gameport
device to obtain mouse button and mouse movement events and with
the timer device to obtain time events. In addition to these
event streams, you can also directly input an event to the input
device, to be fed to the handler chain. This topic is also
covered below.
The keyboard device is also accessible directly. However, while
the input device task is operating, it attempts to retrieve all
incoming keyboard events and add them to the input stream.
The gameport device has two units available to it. As you view
the Amiga looking at the gameport connectors, connector ``1'' is
assigned as the primary mouse input for Intuition and contributes
gameport input events to the input event stream. Connector ``2''
is handled by the other gameport unit and is currently unas-
signed. Each unit of the gameport device is an exclusive access
object, in that you can specify what type of controller is
attached. It is then assumed that only one task is sending
requests for input from that unit. While the input device task
is running, that task expects to read the input from connector 1.
Direct use of the gameport device is covered in a separate
chapter of this manual.
November 13, 1985
- 2 -
The timer device provides time events for the input device. It
also provides time interval reports for controlling key repeat
rate and key repeat threshold. The timer device is a shared-
access device and is described in its own separate section.
1.2. INPUT DEVICE COMMANDS
The input device allows the following system functions:
COMMAND OPERATION
OpenDevice() Obtain shared use of the input device.
CloseDevice() Relinquish use of the input device.
DoIO() Initiate a command, and wait for it to complete.
SendIO() Initiate a command, and return immediately.
AbortIO() Abort a command already in the queue.
Only the Start, Stop, Invalid, and Flush commands have been
implemented for this device. All other commands are no-
operations.
The input device also supports the following device-specific com-
mands:
Table 1-1: Input Device Commands
I/O COMMAND OPERATION
IND_WRITEEVENT Propagate an input event stream to all devices
IND_ADDHANDLER Add an input-stream handler into the
handler chain.
IND_REMHANDLER Remove an input-stream handler from the handler chain.
IND_SETTHRESH Set the repeating key hold-down time before repeat
starts.
IND_SETPERIOD Set the period at which a
repeating key repeats.
IND_SETMPORT Set the gameport port to which the mouse is connected.
IND_SETTRIGGER Read conditions that must be met by a mouse
before a pending read request will be satisfied.
IND_SETMTYPE Set the type of device at the mouse port.
The device-specific commands outlined above are described in the
following paragraphs. A description of the contents of an input
event is given first because the input device deals in input
November 13, 1985
- 3 -
events. An input event is a data structure that describes:
o the class of the event-often describes the device that
generated the event
o the subclass of the event-space for more information if
needed
o the code-keycode if keyboard, button information if
mouse, others
o a qualifier such as ``ALT key also down'', ``key repeat
active''
o a position field which contains a data address or a mouse
position count.
o a time stamp, showing the sequence in which events have
occurred
o a link-field by which input events are linked together
The various types of input events are listed in the include-file
devices/inputevent.h. That information is not repeated here.
You can find more information about input events in the chapters
titled ``Gameport Device'' and ``Console Device''.
There is a difference between simply receiving an input event
from a device (gameport, keyboard, or console) and actually
becoming a handler of an input event stream. A handler is a rou-
tine that is passed an input event, and it is up to the handler
to decide if it can process the input event. If the handler does
not recognize the event, it passes the address of the event as a
return value.
Because of the input event field called ie_NextEvent, it is pos-
sible for the input event to be a pointer to the first event in a
linked list of events to be handled. Thus the handler should be
designed to handle multiple events if such a link is used. Note
that handlers can, themselves, generate new linked lists of
events which can be passed down to lower priority handlers.
You add a handler to the chain by the command IND_ADDHANDLER.
Assuming that you have a properly initialized an IOStdReq block
as a result of a call to OpenDevice() (for the input device),
here is a typical C-language call to the IND_ADDHANDLER function:
November 13, 1985
- 4 -
struct Interrupt handlerStuff;
handlerStuff.is_Data = &hsData;
/* address of its data area */
handlerStuff.is_Code = myhandler;
/* address of entry point to handler */
handlerStuff.is_Node.ln_Pri = 51;
/* set the priority one step higher than
* Intution, so that our handler enters
* the chain ahead of Intuition.
*/
inputRequestBlock.io_Command = IND_ADDHANDLER;
inputRequestBlock.io_Data = &handlerStuff;
DoIO(&inputRequestBlock);
Notice from the above that Intuition is one of the input device
handlers and normally distributes all of the input events.
Intuition inserts itself at priority position 50. You can choose
the position in the chain at which your handler will be inserted
by setting the priority field in the list-node part of the inter-
rupt data structure you are feeding to this routine.
Note also that any processing time expended by a handler sub-
tracts from the time available before the next event happens.
Therefore, handlers for the input stream must be fast.
Rules for Input Device Handlers
The following rules should be followed when you are designing an
input handler:
1. If an input handler is capable of processing a specific
kind of an input event and that event has no links
(ie_NextEvent = 0), the handler can end the handler chain
by returning a NULL (0) value.
2. If there are multiple events linked together, the handler
can feel free to delink an event from the input event
chain, thereby passing a shorter list of events to subse-
quent handlers. The starting address of the modified
list is the return value.
3. If a handler wishes to add new events to the chain that
it passes to a lower priority handler, it may initialize
memory to contain the new event or event chain. The
handler, when it again gets control on the next round of
event handling, should assume nothing about the current
contents of the memory blocks it attached to the event
chain. Lower priority handlers may have modified the
November 13, 1985
- 5 -
memory as they handled their part of the event. The
handler that allocates the memory for this purpose should
keep track of the starting address and the size of this
memory chunk so that the memory can be returned to the
free memory list when it is no longer needed.
Your routine should be structured so that it can be called as
though from the following assembler language statement:
newEventChain = yourHandlerCode(oldEventChain, yourHandlerData);
where:
o yourHandlerCode is the entry point to your routine,
o oldEventChain is the starting address for the current
chain of input events, and
o newEventChain is the starting address of an event chain
which you are passing to the next handler, if any.
A NULL (0) value terminates the handling.
Memory that you use to describe a new input event that you've
added to the event chain is available for re-use or deallocation
when the handler is called again or after the IND_REMHANDLER com-
mand for the handler is complete.
Because IND_ADDHANDLER installs a handler in any position in the
handler chain, it can, for example, ignore specific types of
input events as well as act upon and modify existing streams of
input. It can even create new input events for Intuition or
other programs to interpret.
You remove a handler from the handler chain with the command
IND_REMHANDLER. Assuming that you have a properly initialized
IOStdReq block as a result of a call to OpenDevice() (for the
input device) and you have already added the handler using
IND_ADDHANDLER, here is a typical C-language call to the
IND_REMHANDLER function:
inputRequestBlock.io_Command = IND_REMHANDLER;
inputRequestBlock.io_Data = &handlerStuff;
/* tell it which one to remove */
DoIO(&inputRequestBlock);
As noted in the overview of this chapter, input events are nor-
mally generated by the timer device, keyboard device or gameport
device. A user can also generate an input event and send it to
the input device. It will then be treated as any other event and
passed through to the input handler chain. You can create your
November 13, 1985
- 6 -
own stream of events, then send them to the input device using
the IND_WRITEEVENT command. Here is an example, assuming a
correctly initialized input_request_block. The example sends in
a single event, which is a phony mouse-movement:
struct InputEvent phony;
input_request_block.io_Command = IND_WRITEEVENT;
input_request_block.io_Flags = 0;
input_request_block.io_Length = sizeof(struct InputEvent);
input_request_block.io_Data = &phony;
phony.ie_NextEvent = NULL; /* only one */
phony.ie_Class = IECLASS_RAWMOUSE;
phony.ie_TimeStamp.tv_secs = 0;
phony.ie_TimeStamp.tv_micro = 0;
phony.ie_Code = IECODE_NOBUTTON;
phony.ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
phony.ie_X = 10;
phony.ie_Y = 5;
/* mouse didn't move, but program made
* system think that it did.
*/
DoIO(&input_request_block);
NOTE: This command adds the input event to the end of the
current event stream. The system links other events onto the end
of this event, thus modifying the contents of the data structure
you constructed in the first place.
This command sets the timing in seconds and microseconds for the
input device to indicate how long a user must hold down a key
before it begins to repeat. This command is normally performed
by the Preferences tool or by Intuition when it notices that the
Preferences have been changed. If you wish, you can call this
function. The following typical sequence assumes that you have
already correctly initialized the request block by opening the
input device: Only the fields shown here need be initialized.
struct InputEvent thresh_event;
input_request_block.io_Command = IND_SETTHRESH;
input_request_block.io_Flags = 0;
input_request_block.io_Data = &thresh_event;
thresh_event.ie_NextEvent = 0;
thresh_event.ie_TimeStamp.tv_secs = 1; /* one second */
thresh_event.ie_TimeStamp.tv_micro = 500000;
/* 500,000 microseconds = 1/2 second */
DoIO(&input_request_block);
November 13, 1985
- 7 -
This command sets the time period between key repeat events once
the initial period threshhold has elapsed. Again, it is a com-
mand normally issued by Intuition and preset by the Preferences
tool. A typical calling sequence is as shown above; change the
command number and the timing period values to suit your applica-
tion.
1.3. ADVANCED TOPICS-INPUT DEVICE AND INTUITION
There are several ways to receive information from the various
devices that are part of the input device. The first way is to
communicate directly with the device. This way is, as specified
above, occasionally undesirable (while the input device task is
running). The second way is to become a handler for the stream
of events which the input device produces. That method is also
shown above.
The third method of getting input from the input device is to
retrieve the data from the console device or from the IDCMP
(Intuition Direct Communications Message Port).
If you choose this third method, you should be aware of what hap-
pens to input events if your task chooses not to respond to them.
If there is no active window and no active console, then input
events (key strokes or left button mouse clicks usually) will
simply be ignored. If, however, there is an active window
(yours), and you choose to simply let the messages pile up
without responding to them as quickly as possible, here is what
happens:
o Another event occurs. If the system has no empty message
that it can fill in to report this new event, then memory
is dynamically allocated to hold this new information and
the new message is transmitted to the message port for
the task.
o When the task finally responds to the message, the allo-
cated memory isn't returned to the system until the win-
dow is closed. Therefore, a task that chooses not to
respond to its incoming messages for a long period of
time can potentially remove a great deal of memory from
the system free memory list, making that memory space
unavailable to this or other tasks until this task is
completed.
Thus it is always a good idea to respond to input messages as
quickly as possible to maximize the amount of free memory in the
system while your task is running.
November 13, 1985